package com.study.kt._01grammar._02oop

fun main() {
    var son = Son()
    //访问父类字段
    println(son.name)
    son.sayHello()

    val man = Man("fauks", 12)
    println("${man.name} == ${man.age}")

    //方法与函数转换
    //Father::run：将Father的run方法的引用赋值给run函数
    //函数的类型实际为()->Unit,但是当方法作为单独的函数使用时，需要将方法的原调用者当做参数传入
    //最终函数的类型为接收一个Father的参数，无返回值
    val run: (Father) -> Unit = Father::run
    run(Father())

    val eat = Father::eat
    val res = eat(Father(), "鸡腿")
    println(res)
}

//继承父类的主构造函数
open class Human(var name: String, var age: Int)

//父类的主构造函数的参数，必须通过子类构造函数传递过去
class Man(name: String, age: Int) : Human(name, age)

//继承
//如果一个类可以被继承需要使用open修饰类，如果不加open，类默认为final class
open class Father {
    //属性或方法默认为final，使用open修饰表示可以被重写
    open var name: String = "father"

    open fun sayHello() {
        println("father hello")
    }

    fun run() {
        println("Father run。。。")
    }

    fun eat(food: String): String {
        return "Father eat $food"
    }
}

//继承与接口都使用 :表示
class Son : Father() {
    //override表示复写父类属性，需要显示指定
    override var name: String = "son"

    override fun sayHello() {
        println("son hello")
    }
}

//封装
class Op1 {
    fun eat() {
        step1()
        step2()
    }

    //使用private修饰，进行封装
    private fun step1() {
        println("洗手")
    }

    private fun step2() {
        println("吃")
    }
}

// 一个没有主构造的类继承有参构造父类，就需要通过次构造调用父类构造
open class Parent(name: String)
class Child : Parent {
    constructor(name: String) : super(name)
}

// 一个类继承、实现多个类/接口，而且他们有相同的方法签名，这个类必须复写相关方法
interface A {
    fun method() {
        println("interface A")
    }
}

open class B {
    open fun method() {
        println("class B")
    }
}

class C : A, B() {
    override fun method() {
        // 需要显示的声明调用哪一个父类的方法
        super<A>.method()
        super<B>.method()
    }
}
